package com.demo.steammanagement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.demo.steammanagement.common.QueryBuild;
import com.demo.steammanagement.common.ResultMsg;
import com.demo.steammanagement.config.response.BizException;
import com.demo.steammanagement.convert.RentalsConvert;
import com.demo.steammanagement.enums.GameCategoryEnum;
import com.demo.steammanagement.enums.UserRoleEnum;
import com.demo.steammanagement.mapper.GameAccountsMapper;
import com.demo.steammanagement.mapper.GamesMapper;
import com.demo.steammanagement.mapper.UsersMapper;
import com.demo.steammanagement.model.entity.GameAccounts;
import com.demo.steammanagement.model.entity.Games;
import com.demo.steammanagement.model.entity.Rentals;
import com.demo.steammanagement.model.entity.Users;
import com.demo.steammanagement.model.vo.RentalVO;
import com.demo.steammanagement.model.vo.UserVO;
import com.demo.steammanagement.service.IRentalsService;
import com.demo.steammanagement.mapper.RentalsMapper;
import com.demo.steammanagement.service.IUsersService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * @author Administrator
 * @description 针对表【rentals(记录用户的租用历史)】的数据库操作Service实现
 * @createDate 2024-12-09 15:45:45
 */
@Service
public class IRentalsServiceImpl extends ServiceImpl<RentalsMapper, Rentals>
        implements IRentalsService {

  @Autowired
  private UsersMapper usersMapper;

  @Autowired
  private GameAccountsMapper gameAccountsMapper;
  @Autowired
  private RentalsMapper rentalsMapper;
  @Autowired
  private GamesMapper gamesService;
  @Autowired
  private IUsersService userService;
  @Autowired
  private GamesMapper gamesMapper;

  @Override
  @Transactional
  public Boolean costomSaveOrUpdate(RentalVO vo) {
    if (ObjectUtils.isEmpty(vo)) {
      throw new BizException(ResultMsg.OBJECT_IS_EMPTY.getMsg());
    }
    if (ObjectUtils.isEmpty(vo.getUserName())) {
      throw new BizException(ResultMsg.NOT_LOGIN.getMsg());
    }
    if (ObjectUtils.isEmpty(vo.getGameAccountId())) {
      throw new BizException(ResultMsg.PLEASE_SELECT_ACCOUNT.getMsg());
    }
    String username = SecurityContextHolder.getContext().getAuthentication().getName();
    Users user = userService.getUserByUsername(username);
    if ("4".equals(user.getUserRole()) || "3".equals(user.getUserRole())) {
      // 获取用户的账户过期日期
      LocalDateTime accountExpirationDate = user.getAccountExpirationDate();
      // 获取当前时间
      LocalDateTime now = LocalDateTime.now();
      // 比较两个日期
      if (accountExpirationDate == null || !accountExpirationDate.isAfter(now)) {
        throw new BizException("会员已过期: " + username);
      }
    }
    // 获取游戏分类
    Games games = gamesService.selectById(vo.getGameId());
    if(UserRoleEnum.COMMON_MEMBER.getCode().equals(user.getUserRole())){
      if(games.getCategory().equals(GameCategoryEnum.HIGH_LEVEL.getCode())){
        throw new BizException("高级会员才能租高级游戏: " + username);
      }
    }
    // 查询是否有账号是否被租用    如果第一次租用count是0  有一个租用是1
    Long count = rentalsMapper.selectCount(new LambdaQueryWrapper<Rentals>()
            .eq(Rentals::getUserId, user.getId())
            .eq(Rentals::getStatus, 1)
    );
    if (count > 0) {
      throw new BizException("每次只能租一个游戏，请先停止其他游戏");
    }
    vo.setStartTime(new Date());
    long time = new Date().getTime() + 24 * 60 * 60 * 1000;
    vo.setEndTime(new Date(time));
    vo.setUserId(user.getId());
    // 获取游戏账号名称
    GameAccounts gameAccounts = gameAccountsMapper.selectByIdWithLock(vo.getGameAccountId());
    if (ObjectUtils.isNotEmpty(gameAccounts)) {
      vo.setAccount(gameAccounts.getGameAccount());
    }
    Integer status = gameAccounts.getStatus();
    if (status != 0) {
      throw new BizException(ResultMsg.ACCOUNT_IS_NOT_AVAILABLE.getMsg());
    }
    vo.setCreatedAt(new Date());
    vo.setUpdatedAt(new Date());
    return this.saveOrUpdate(RentalsConvert.INSTANCE.convertVOToEntity(vo));
  }

  @Transactional
  @Override
  public void updateExpiredRentals() {
    // 查询所有过期租号记录  结束时间大于现在时间
    LambdaQueryWrapper<Rentals> queryWrapper = new LambdaQueryWrapper<Rentals>()
            .lt(Rentals::getEndTime, LocalDateTime.now())
            .eq(Rentals::getStatus, 1);
    List<Rentals> expiredRentals = rentalsMapper.selectList(queryWrapper);

    for (Rentals rental : expiredRentals) {
      // 更新租号记录状态为“已结束”
      rental.setStatus(0);
      rentalsMapper.updateById(rental);
      // 更新游戏账号状态为“空闲”
      gameAccountsMapper.update(new LambdaUpdateWrapper<GameAccounts>()
              .set(GameAccounts::getStatus, 0)
              .eq(GameAccounts::getId, rental.getGameAccountId())
      );
      // 更游戏当前可租用的账号数量
      Long count = gameAccountsMapper.selectCount(new LambdaQueryWrapper<GameAccounts>()
              .eq(GameAccounts::getGameId, rental.getGameId())
              .eq(GameAccounts::getStatus, 0)
      );
      gamesMapper.update(new LambdaUpdateWrapper<Games>()
              .set(Games::getAvailableAccounts, count)
              .eq(Games::getId, rental.getGameId()));
    }
  }
}




